#ifndef _basic_bitstream_impl_hpp_
#define _basic_bitstream_impl_hpp_

/** \file basic_bitstream_impl.hpp
 *  \author Adrian Schweizer
 *  \created  $Sa 18 Aug 03:48:01 pm CEST 2007 schwadri@SchwadriComp.local$
 *  \modified $Do 30 Aug 12:22:34 pm CEST 2007 schwadri@SchwadriComp.local$
 */

namespace core {

    //structors
    template<class Impl>
        basic_bitstream<Impl>::basic_bitstream()
        :   m_impl()
        { }

    template<class Impl>
        basic_bitstream<Impl>::basic_bitstream(size_type init_size)
        :   m_impl(init_size)
        { }

    template<class Impl>
        basic_bitstream<Impl>::basic_bitstream(block_type* data, size_type byte_count, bool copy_data)
        :   m_impl(data,byte_count,copy_data)
        { }

    template<class Impl>
        basic_bitstream<Impl>::basic_bitstream(basic_bitstream<Impl>& other, bool copy_data)
        :   m_impl(other.m_impl,copy_data)
        { }

    template<class Impl>
        template<class OImpl>
        basic_bitstream<Impl>::basic_bitstream(const basic_bitstream<OImpl>& other, bool copy_data)
        :   m_impl(other.m_impl,copy_data)
        { }

    template<class Impl>
        template<class Container>
        basic_bitstream<Impl>::basic_bitstream(Container& data, bool copy_data)
        :   m_impl(data,copy_data)
        { }

    template<class Impl>
        template<class BlockInputIterator>
        basic_bitstream<Impl>::basic_bitstream(BlockInputIterator begin, BlockInputIterator end)
        :   m_impl(begin,end)
        { }

    //destructor
    template<class Impl>
        basic_bitstream<Impl>::~basic_bitstream()
        { }

    template<class Impl>
        void basic_bitstream<Impl>::reserve(size_type size)
        {
            m_impl.reserve(size);
        }

    template<class Impl>
        void basic_bitstream<Impl>::reset()
        {
            m_impl.reset();
        }

    //write methods
    template<class Impl>
        template<class T>
        inline void basic_bitstream<Impl>::write(const T& var)
        {
            m_impl.write(var);
        }

    template<class Impl>
        template<class BlockInputIterator>
        void basic_bitstream<Impl>::write_aligned(BlockInputIterator begin, BlockInputIterator end)
        {
            m_impl.write_aligned(begin,end);
        }


    template<class Impl>
        template<class T>
        void basic_bitstream<Impl>::write_aligned(const T &var)
        {
            return m_impl.write_aligned(var);
        }

    template<class Impl>
        void basic_bitstream<Impl>::write(const char* input, size_type byte_count)
        {
            m_impl.write(reinterpret_cast<const unsigned char*>(input),byte_count);
        }

    template<class Impl>
        void basic_bitstream<Impl>::write_bits(const unsigned char *input, size_type bit_count, bool right_aligned)
        {
            m_impl.write_bits(input,bit_count,right_aligned);
        }

    template<class Impl>
        void basic_bitstream<Impl>::write_aligned_bytes(const unsigned char* input, size_type byte_count)
        {
            m_impl.write_aligned_blocks(input,byte_count);
        }

    template<class Impl>
        unsigned char&  basic_bitstream<Impl>::operator[](size_type pos)
        {
            return m_impl[pos];
        }
    template<class Impl>
        unsigned char   basic_bitstream<Impl>::operator[](size_type pos) const
        {
            return m_impl[pos];
        }

    template<class Impl>
        template<class ForwardIterator>
        bool basic_bitstream<Impl>::read_aligned(ForwardIterator begin, ForwardIterator end)
        {
            return m_impl.read_aligned(begin,end);
        }

    //read methods
    template<class Impl>
        bool basic_bitstream<Impl>::read(char* output, size_type byte_count)
        {
            return m_impl.read(reinterpret_cast<unsigned char*>(output),byte_count);
        }

    template<class Impl>
        bool basic_bitstream<Impl>::read_aligned_bytes(unsigned char* output,
                                                        size_type byte_count)
        {
            return m_impl.read_aligned_blocks(output,byte_count);
        }

    template<class Impl>
        bool basic_bitstream<Impl>::read_bits(unsigned char* output,
                                              size_type bit_count, bool right_aligned)
        {
            return m_impl.read_bits(output,bit_count,right_aligned);
        }

    template<class Impl>
        template<class T>
        inline bool basic_bitstream<Impl>::read(T &var)
        {
            return m_impl.read(var);
        }

    template<class Impl>
        template<class T>
        inline bool basic_bitstream<Impl>::read_aligned(T &var)
        {
            return m_impl.read_aligned(var);
        }

    //navigation methods
    template<class Impl>
        void basic_bitstream<Impl>::seekg(pos_type pos)
        {
            m_impl.seekg(pos,beg);
        }

    template<class Impl>
        void basic_bitstream<Impl>::seekg(pos_type pos,rel_type rel)
        {
            m_impl.seekg(pos,rel);
        }

    template<class Impl>
        void basic_bitstream<Impl>::seekp(pos_type pos,rel_type rel)
        {
            m_impl.seekp(pos,rel);
        }

    template<class Impl>
        typename basic_bitstream<Impl>::pos_type    basic_bitstream<Impl>::tellg() const
        {
            return m_impl.tellg();
        }


    template<class Impl>
        void basic_bitstream<Impl>::alignp()
        {
            m_impl.alignp();
        }

    template<class Impl>
        void basic_bitstream<Impl>::aligng()
        {
            m_impl.aligng();
        }


    template<class Impl>
        void basic_bitstream<Impl>::set_number_of_bits_allocated(size_type bit_count)
        {
            m_impl.set_number_of_bits_allocated(bit_count);
        }

    template<class Impl>
        void basic_bitstream<Impl>::set_data(const unsigned char* input, const size_type bit_count)
        {
            m_impl.set_data(input,bit_count);
        }

    /*template<class Impl>
        void basic_bitstream<Impl>::add_bits_and_reallocate(size_type bit_count)
        {
            m_impl.add_bits_and_reallocate(bit_count);
        }*/

    template<class Impl>
        int basic_bitstream<Impl>::copy_data(unsigned char*& data) const
        {
            return m_impl.copy_data(data);
        }

    template<class Impl>
        void basic_bitstream<Impl>::ignore(size_type bit_count)
        {
            m_impl.ignore(bit_count);
        }

    template<class Impl>
        void basic_bitstream<Impl>::ignore()
        {
            m_impl.ignore();
        }


    template<class Impl>
        void basic_bitstream<Impl>::seekp(pos_type offset)
        {
            m_impl.seekp(offset,beg);
        }

    template<class Impl>
        typename basic_bitstream<Impl>::pos_type    basic_bitstream<Impl>::tellp() const
        {
            return m_impl.tellp();
        }

    template<class Impl>
        int basic_bitstream<Impl>::size() const
        {
            return m_impl.size();
        }

    template<class Impl>
        int basic_bitstream<Impl>::size_bytes() const
        {
            return m_impl.size_bytes();
        }

    template<class Impl>
        unsigned char* basic_bitstream<Impl>::get_data() const
        {
            return m_impl.get_data();
        }
    template<class Impl>
        basic_bitstream<Impl>::operator bool() const
        {
            return m_impl.operator bool();
        }
    template<class Impl>
        template<class T>
        boost::optional<T>   basic_bitstream<Impl>::peek() const
        {
            return m_impl.peek<T>();
        }

    template<class Impl>
        template<class T>
        boost::optional<T>   basic_bitstream<Impl>::peek_aligned() const
        {
            return m_impl.peek_aligned<T>();
        }

} // namespace core

#endif // _basic_bitstream_impl_hpp_
